• 検索結果がありません。

6.5 美しいプログラムを | 字下げと変数名

6.5.1 字下げ

???

...

...

..........

......

..........

......

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . ... . . . . . . . . . . ... . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . .. . .

. . . . . . . . . . . . . . . . . . . . . .

. .

. .

. .

. .

. . .

.

. . .

.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. .

. .

. .

.

. .

. .

.

. .

. .

. .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . .

. . . . . . .

. . . . . .

........

......

. ...

. .

.

. .

. .

. . .

.

. .

. .

. . .

. .

.

. . . .

. .

. . .

. . . .

. . .

. .

. . . . .

. . . .

. . .

. . . . . .

. . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . . . . . .

. . .

. . . . .

. . .

. . . . . .

..................

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . .. . . . . . . . .. . . . . .. . . . . . . . . .. . . . .. . .. ... . .. . . . ... .. . . .. .. ..... .. ..... ... . . .

. . . . . .. ... . . .. .. .. . .

. . . .

. . . . . .

. . . . . .

. .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . .. . . . . . . . .. . . . . .. . . . . . . . . .. . . . .. . .. ... . .. . . . ... .. . . .. .. ..... .. ..... ... . . .

. . . . . .. ... . . .. .. .. . .

. . . .

. . . . . .

. . . . . .

. .

???

(a)

letrec

(b)

let

(define (is-even-number? n)

(lambda (n) (if (zero? n) #t (odd? (- n 1)))))

(even? n))) (odd?

(lambda (n) (if (zero? n) #f (even? (- n 1))))) ) (let

(define (is-even-number? n)

(lambda (n) (if (zero? n) #t (odd? (- n 1)))))

(even? n))) (letrec

(odd?

(lambda (n) (if (zero? n) #f (even? (- n 1))))) )

(even?

(even?

(

(

6.8:

letrec let

; procedure "factorial"

; --- computes factorial of n : n! = n (n-1) (n-2) ... 1

; argument: n - integer (must be positive) (define (factorial n)

(if (= n 1) 1

(* n (factorial (- n 1)))))

(a)

美しいプログラム

;; purocedure f

(define (f x) (if (= x 1) 1 (* x (f (- x 1)))))

(b)

見にくいプログラム

6.9:

いろいなプログラムの書き方

階乗を計算する

2

つのプログラムを図

6.5.1(b)

(c)

に示します。これらは同じ計算をし ますが 、図

6.5.1(a)

の方が読みやすくなっています。引数の意味や手続きが何を計算する かが 、コメントとして明確に記述されています。いっぽ う

(b)

の方は何を計算する手続き なのかが記述されておらず、さらにプログラム自体も変な位置で改行してあるため、プロ グラムの構造が一目で理解できません。さらに手続きの名前も単に f としているだけで、

手続き名から何をする手続きかを連想することが難しくなっています。

プログラムの構造が一目で分かるよう、行のはじめの部分に適切な数の空白文字をいれ ることを字下げ

(indent)

といいます。図

6.5.1(a)

では適切な位置で改行をし 、ちょうどい い数の空白文字が入れられています。

たとえ適切な位置で改行しても空白文字の数が適切でないと、プログラムの構造を簡単 には読みとれません。こんどはフィボナッチ数列

F i =

8

>

>

<

>

>

:

1 n = 1

のとき

1 n = 2

のとき

F i

,1

+ F i

,2

n

3

のとき

を例にします。図

6.5.1(a),(b)

は、フィボナッチ数列の

n

番目の数を計算するプログラム で、それぞれ字下げだけを変えたものです。

6.5.1(b)

では変な字下げがされているために、プログラムがフィボナッチ数列の定義

に合っているかど うかを確かめるのは大変です。

プログラムの字面が美しかろうが醜かろうが 、プログラムの動作の正しさそのものには 関係はありません。ですがプログラムを作成する段階で正しい字下げをし 、適切な変数名 を選ぶことで、プログラムに誤りが入る可能性はずっと減ります。別な見方をすれば 、プ

; compute n-th Fibonacci (define (fibonacci n)

(if (= n 1) 1

(if (= n 2) 1

(+ (fibonacci (- n 1)) (fibonacci (- n 2))))))

(a)

良い字下げ

; compute n-th Fibonacci (define (fibonacci n)

(if (= n 1) 1

(if (= n 2) 1

(+ (fibonacci (- n 2)) (fibonacci (- n 1))))))

(b)

良くない字下げ

6.10:

字下げ

ログラムの間違い探しに時間を費やすこることを避けるためにも、字下げと変数名には注 意を払うべきです14

以下では

Scheme

での字下げの方法のいくつかを示します。字下げのルールは人の好み

によって違いますので、どれが良いとは一概にはいえません。ここでは筆者が使っている 字下げの方法を紹介します。大原則のひとつは、ひとつの行が画面の右端を越えないよう にする、ということです。画面の幅はたいてい

80

文字で 、これを越えた長さの行は画面 の次の行に折り返されて、画面の左端から表示される場合が多いです。もしそのように表 示されると、プログラムの構造を読みとるのが困難になります。そのためにも、

1

行 を

80

文字以下にすることを奨めます。

define 構文

手続きの本体を

2

つの空白を入れて字下げします。

(define (h手続き名i h引数のならび i)

h手続きの本体i)

14プログラムの字下げを自動的にしてくれるソフトウエアがあります。ですが 、いい加減な字下げでプロ グラムを書き、一番最後に字下げプログラムを使って字下げして完成品にすることは、上記の趣旨に反する ことなのでするべきではありません。

手続きでないときは、次のようにします。

(define h変数名i hi)

もし hiが長くて画面の右端を越えるときは、次のようにします。

(define h変数名i

hi)

if 構文

if の中の式を、

2

つの空白を入れて字下げします。

(if hi

h1i)

あるいは (if hi

h1i)

h2i)

cond 構文

cond 構文は、 節がならぶように書きます。

(cond

(hテスト1i hi ) ...

(hテスト

n

i hi ))

もし hテスト iが長いときは、次のようにします。

(cond

(hテスト1i

hi )

...

(hテスト

n

i

hi ))

let 構文

局所変数と本体とで字下げを変えて、 区別しやすくします。

(let ((h変数1

i h1

i) ...

(h変数

n

i h

n

i))

h1i

...

h

n

i)

もし局所変数の初期値を与える式が長いときは、 次のようにします。

(let ((h変数1i

h1i)

...

(h変数

n

i

h

n

i))

h1i

...

h

n

i)

もし局所変数のならびが特に短いときは、 一行で書くこともあります。

(let ((h変数1i h1i) (h変数

n

i h

n

i))

h1i

...

h

n

i)

一般の式

一般の式は、手続き名とそれに対する引数のならびから成ります。引数のならびが 短いときは、一行で書きます。

(h手続きi hi hi)

もし一行に書き切れないときは途中で改行をしますが 、引数は h手続きi よりも右 に寄せます。

(h手続きi hi hi

hi hi

...

hi hi)

または

(h手続きi

hi hi

hi hi

...

hi hi)

とします。もし hiが長いときは、一行にひとつの式を書きます。

6.5.2 手続きと変数の名前

変数と手続きの名前について考えます。プログラムを書くときには色々な変数を使いま すが 、何のために使われているかを表した変数名にすることで、プログラムが読みやすく なります。

6.5.1

には、価格のリストと税率から消費税の総和を計算する

3

つのプログラムが示

されています。

(a),(b),(c)

いずれも、その手続きが何をするものかがコメントとして記述 してあります。図

6.5.1(a)

では、仮引数の名前が b

,

cなために、引数として何を与えて良 いのかがまったく分かりません。そのために、プログラムの中身を解読しないと使えませ ん。

(a)

を改良したのが

(b)

です。このプログラムでは、どの引数が何の役割をしているか をコメントとして記述してあるために、その手続きを利用することができます。

(a)

(b)

も、そのプログラムがすることと関連性のない Sを手続きの名前にしていま す。この名前だとすぐにでも忘れてしまいそうです。また別のプログラムの中で Sが現れ ても、そのプログラムを読むひとはそれが何をする手続きかさっぱり分からないでしょう。

プログラム

(c)

では、手続きの名前と引数の名前ともに、どのような役割を持つものか を名前にしています。また手続きの最初の部分には、どのようにして使うかがコメントと して詳しく書かれているために、この部分を見るだけで使い方がすぐ 分かります。

こんどは手続きを作成している時点のことを考えてみましょう。ここで挙げた例はいず れも紙面の都合で短いものだけですが 、実際のプログラムはこれよりも長く複雑です。そ のような場合に、変数名が bや cだったらど うでしょうか

?

どの変数が何の役割をしてい るかをすべて記憶するのは大変です。変数の数が増えてくるとそれらを完全に憶えること はまず不可能で、必ずといっていいくらい勘違いをしてしまいます。

コメントに書いておけばいいと思われるかも知れませんが 、そのようなことに努力する よりも、適切な変数名を選び 、プログラムの構造を良くするべきです。図

6.5.1(c)

のプロ

グラムでは、手続きの名前や変数名は少々長めですが 、こうすることでプログラム自体が 読みやすくなるとともに、ケアレスミスによってプログラムにバグ

(

プログラムの間違い

)

を入れてしまうことが少なくなります。

以上のように、字下げや適切な変数名を選ぶことは、プログラムの読みやすさ、書きや すさの点から大変重要です。美しいプログラムを追求するということは、見た目のきれい

;; SYOUHIZEI (define (S b c)

(if (null? b) 0

(+ (* c (car b)) (S (cdr b) c))))

(a)

悪い例

1

;; procedure "S"

;; - computes SYOUHIZEI

;; argument: b - list of price

;; c - tax rate

(define (S b c) (if (null? b)

0

(+ (* c (car b)) (S (cdr b) c))))

(b)

悪い例

2

;; procedure "SyouhiZei"

;; - computes sum of SYOUHIZEI of each item

;; argument: list-of-price - list of price (e.g. )

;; tax-rate - tax rate (e.g. be 0.03)

;; Example:

;; (SyouhiZei '(1000 200 800) 0.03)

;; ---> 60 = 0.03*1000+0.03*200+0.03*800

;;

(define (SyouhiZei list-of-price tax-rate) (if (null? list-of-price)

0

(+ (* tax-rate (car list-of-price))

(SyouhiZei (cdr list-of-price) tax-rate))))

(c)

良い例

6.11:

変数の名前の選び方

さだけでなく、プログラムの内容そのものに十分な配慮を加え、質の高いプログラムを書 こうとする行為にほかなりません。

初心者にとっては、最初から美しいプログラムを書くことは難しいことです。プログラ ムが動き出したあとは放り投げるのではなく、より美しいプログラムにするために、何度 も書き換えてみてください。徐々にいいプログラムを書く技能が身についてゆくことと思 います。更に詳しく勉強したい人は、以下の文献を参考にして下さい。

B. W. Kernighan, P. J. Plauger (

木村 泉 訳

), \

プログラム書法

",

第二版

,

共立出版

, 1982.

B. W. Kernighan, P. J. Plauger (

木村 泉 訳

), \

ソフトウエア作法

",

共立出版

, 1981.

F. P. Brooks Jr. (

山内 正彌 訳

), \

ソフトウエア開発の神話

",

企画センター

, 1977.

D. E. Knuth (

有澤 誠 訳

), \

文芸的プログラミング

",

アスキー出版局

, 1994.

筧 捷彦 他

, \

プログラミングセミナー

",

共立出版

, 1985.

ああ、死んだ作家は仕合せだ。生き長らえてゐる愚作者は、おのれの作品をひとりで も多くのひとに愛されようと、汗を流して見當はづれの註釋ばかりつけてゐる。そし て、まづまづ註釋だらけのうるさい駄作をつくるのだ。

太宰治 「道化の華」

太宰治全集第一巻収録 昭和四十二年 筑摩書房刊

NGSCM の編集コマンド

この章では

NGSCM

の編集コマンド について学びます。

NGSCM

では複数のファイル

を同時に編集したり、画面を複数に分割して別のファイルを参照しながら編集する機能が 用意されています。これらの機能はそれぞれ 、マルチバッファ機能、マルチウインド ウ機 能と呼ばれています。

NGSCM

にはこの他いろいろな編集機能がありますが 、すべてを説 明することは誌面の都合上しません。